Import Data

corrcounts_merge <- readRDS("~/VersionControl/senescence_benchmarking/Data/corrcounts_merge.rds")
metadata_merge <- readRDS("~/VersionControl/senescence_benchmarking/Data/metadata_merge.rds")
SenescenceSignatures <- readRDS("~/VersionControl/senescence_benchmarking/CommonFiles/SenescenceSignatures_divided_newCellAge.RDS")
library(markeR)
library(ggplot2)
library(ggpubr)
library(edgeR)
Loading required package: limma
?markeR
ℹ Rendering development documentation for "markeR"

Scores

?CalculateScores
ℹ Rendering development documentation for "CalculateScores"

Unidirectional

df_ssGSEA <- CalculateScores(data = corrcounts_merge, metadata = metadata_merge, method = "ssGSEA", gene_sets = SenescenceSignatures)
Considering unidirectional gene signature mode for signature [DOWN]_CellAge
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature [DOWN]_HernandezSegura
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature [DOWN]_SeneQuest
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature [UP]_CellAge
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature [UP]_HernandezSegura
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature [UP]_SeneQuest
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature CSgene
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature GOBP_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature GOBP_NEGATIVE_REGULATION_OF_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature GOBP_POSITIVE_REGULATION_OF_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature REACTOME_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature SAUL_SEN_MAYO
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
senescence_triggers_colors <- c(
  "none" = "#E57373",  # Soft red  
  "Radiation" = "#BDBDBD",  # Medium gray  
  "DNA damage" = "#64B5F6",  # Brighter blue  
  "Telomere shortening" = "#4FC3F7",  # Vivid sky blue  
  "DNA demethylation" = "#BA68C8",  # Rich lavender  
  "Oxidative stress" = "#FDD835",  # Strong yellow  
  "Conditioned Medium" = "#F2994A",  # Warm orange  
  "Oncogene" = "#81C784",  # Medium green  
  "Lipid Accumulation" = "#E57373",  # Coral  
  "Calcium influx" = "#26A69A",  # Deep teal  
  "Plasma membrane dysruption" = "#D32F2F",  # Strong salmon  
  "OSKM factors" = "#FFB74D",  # Bright peach  
  "YAP KO" = "#9575CD"  # Deep pastel purple  
)

cellTypes_colors <- c(
  "Fibroblast" = "#FF6961",   # Strong Pastel Red  
  "Keratinocyte" = "#FFB347", # Strong Pastel Orange  
  "Melanocyte" = "#FFD700",   # Strong Pastel Yellow  
  "Endothelial" = "#77DD77",  # Strong Pastel Green  
  "Neuronal" = "#779ECB",     # Strong Pastel Blue  
  "Mesenchymal" = "#C27BA0"   # Strong Pastel Purple  
)

cond_cohend <- list(A=c("Senescent"), # if no variable is defined, will be the first that appears in the ggplot
                    B=c("Proliferative","Quiescent"))

PlotScores(ResultsList = df_ssGSEA, ColorVariable = "CellType", GroupingVariable="Condition",  method ="ssGSEA", ColorValues = cellTypes_colors, ConnectGroups=TRUE, ncol = 6, nrow = 2, widthTitle=20, y_limits = NULL, legend_nrow = 2,cond_cohend=cond_cohend)

df_logmedian <- CalculateScores(data = corrcounts_merge, metadata = metadata_merge, method = "logmedian", gene_sets = SenescenceSignatures)

senescence_triggers_colors <- c(
  "none" = "#E57373",  # Soft red  
  "Radiation" = "#BDBDBD",  # Medium gray  
  "DNA damage" = "#64B5F6",  # Brighter blue  
  "Telomere shortening" = "#4FC3F7",  # Vivid sky blue  
  "DNA demethylation" = "#BA68C8",  # Rich lavender  
  "Oxidative stress" = "#FDD835",  # Strong yellow  
  "Conditioned Medium" = "#F2994A",  # Warm orange  
  "Oncogene" = "#81C784",  # Medium green  
  "Lipid Accumulation" = "#E57373",  # Coral  
  "Calcium influx" = "#26A69A",  # Deep teal  
  "Plasma membrane dysruption" = "#D32F2F",  # Strong salmon  
  "OSKM factors" = "#FFB74D",  # Bright peach  
  "YAP KO" = "#9575CD"  # Deep pastel purple  
)

cellTypes_colors <- c(
  "Fibroblast" = "#FF6961",   # Strong Pastel Red  
  "Keratinocyte" = "#FFB347", # Strong Pastel Orange  
  "Melanocyte" = "#FFD700",   # Strong Pastel Yellow  
  "Endothelial" = "#77DD77",  # Strong Pastel Green  
  "Neuronal" = "#779ECB",     # Strong Pastel Blue  
  "Mesenchymal" = "#C27BA0"   # Strong Pastel Purple  
)

cond_cohend <- list(A=c("Senescent"), # if no variable is defined, will be the first that appears in the ggplot
                    B=c("Proliferative","Quiescent"))

PlotScores(ResultsList = df_logmedian, ColorVariable = "CellType", GroupingVariable="Condition",  method ="logmedian", ColorValues = cellTypes_colors, ConnectGroups=TRUE, ncol = 6, nrow = 2, widthTitle=20, y_limits = NULL, legend_nrow = 2,xlab=NULL, cond_cohend = cond_cohend)

df_ranking <- CalculateScores(data = corrcounts_merge, metadata = metadata_merge, method = "ranking", gene_sets = SenescenceSignatures)
Considering unidirectional gene signature mode for signature [DOWN]_CellAge
Considering unidirectional gene signature mode for signature [DOWN]_HernandezSegura
Considering unidirectional gene signature mode for signature [DOWN]_SeneQuest
Considering unidirectional gene signature mode for signature [UP]_CellAge
Considering unidirectional gene signature mode for signature [UP]_HernandezSegura
Considering unidirectional gene signature mode for signature [UP]_SeneQuest
Considering unidirectional gene signature mode for signature CSgene
Considering unidirectional gene signature mode for signature GOBP_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_NEGATIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_POSITIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature REACTOME_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature SAUL_SEN_MAYO
senescence_triggers_colors <- c(
  "none" = "#E57373",  # Soft red  
  "Radiation" = "#BDBDBD",  # Medium gray  
  "DNA damage" = "#64B5F6",  # Brighter blue  
  "Telomere shortening" = "#4FC3F7",  # Vivid sky blue  
  "DNA demethylation" = "#BA68C8",  # Rich lavender  
  "Oxidative stress" = "#FDD835",  # Strong yellow  
  "Conditioned Medium" = "#F2994A",  # Warm orange  
  "Oncogene" = "#81C784",  # Medium green  
  "Lipid Accumulation" = "#E57373",  # Coral  
  "Calcium influx" = "#26A69A",  # Deep teal  
  "Plasma membrane dysruption" = "#D32F2F",  # Strong salmon  
  "OSKM factors" = "#FFB74D",  # Bright peach  
  "YAP KO" = "#9575CD"  # Deep pastel purple  
)

cellTypes_colors <- c(
  "Fibroblast" = "#FF6961",   # Strong Pastel Red  
  "Keratinocyte" = "#FFB347", # Strong Pastel Orange  
  "Melanocyte" = "#FFD700",   # Strong Pastel Yellow  
  "Endothelial" = "#77DD77",  # Strong Pastel Green  
  "Neuronal" = "#779ECB",     # Strong Pastel Blue  
  "Mesenchymal" = "#C27BA0"   # Strong Pastel Purple  
)

cond_cohend <- list(A=c("Senescent"), # if no variable is defined, will be the first that appears in the ggplot
                    B=c("Proliferative","Quiescent"))

PlotScores(ResultsList = df_ranking, ColorVariable = "CellType", GroupingVariable="Condition",  method ="ranking", ColorValues = cellTypes_colors, ConnectGroups=TRUE, ncol = 6, nrow = 2, widthTitle=20, y_limits = NULL, legend_nrow = 2,xlab=NULL, cond_cohend = cond_cohend)

wrap_title_aux <- function(title, width = 30) {
  if (nchar(title) <= width) {
    return(title)  # No need to wrap if it fits
  }
  
  wrapped_title <- ""
  while (nchar(title) > width) {
    # Find positions of capital letters and symbols near the wrap point
    capital_pos <- gregexpr("[A-Z]", title)[[1]]
    symbol_pos <- gregexpr("(_|-|:)", title)[[1]]
    
    # Check for symbol breaks within the last few characters (width - 5 to width)
    valid_symbol_breaks <- symbol_pos[symbol_pos >= (width - 5) & symbol_pos <= width]
    
    if (length(valid_symbol_breaks) > 0) {
      # If a suitable symbol is found, break at the first valid symbol
      break_at <- valid_symbol_breaks[1]
    } else {
      # If no suitable symbol, look for capital letters within the same range
      valid_capital_breaks <- capital_pos[capital_pos >= (width - 5) & capital_pos <= width]
      
      if (length(valid_capital_breaks) > 0) {
        # If a capital letter is found, break just before the capital letter
        break_at <- valid_capital_breaks[1] - 1
      } else {
        # If no suitable symbol or capital letter, break at width
        break_at <- width
      }
    }
    
    # Append the wrapped line
    wrapped_title <- paste0(wrapped_title, substr(title, 1, break_at), "\n")
    
    # Update title with the remaining text after the break
    title <- substr(title, break_at + 1, nchar(title))
  }
  
  # Add the remaining part of the title
  wrapped_title <- paste0(wrapped_title, title)
  
  return(wrapped_title)
}

plotlist <- list()

for (sig in names(df_ssGSEA)){
  
  df_subset_ssGSEA <- df_ssGSEA[[sig]]
  df_subset_logmedian <- df_logmedian[[sig]]
  
  df_subset_merge <- merge(df_subset_ssGSEA,df_subset_logmedian,by="sample")
  
  # Wrap the signature name using the helper function
  wrapped_title <- wrap_title_aux(sig, width = 20)  
  
  plotlist[[sig]] <- ggplot2::ggplot(df_subset_merge, aes(x=score.x, y=score.y)) +
    geom_point(size=4, alpha=0.8, fill="darkgrey", shape=21) +
    theme_bw() +
    xlab("ssGSEA Enrichment Score") +
    ylab("Normalised Signature Score") +
    ggtitle(wrapped_title) +
    theme(plot.title = ggplot2::element_text(hjust = 0.5, size=10),
          plot.subtitle = ggplot2::element_text(hjust = 0.5)) 
  
}
Error in names(df_ssGSEA) : object 'df_ssGSEA' not found

Bidirectional gene signatures

Try scores with bidirectional signatures

bidirectsigs <- readRDS("~/VersionControl/senescence_benchmarking/CommonFiles/SenescenceSignatures_complete_newCellAge.RDS")
for (sig in names(bidirectsigs)){
  sigdf <- bidirectsigs[[sig]]
  sigdf <- sigdf[,1:2] # remove the third column, if applicable
  if(any(sigdf[,2]=="not_reported")){
    sigdf <- sigdf[,1]
    bidirectsigs[[sig]] <- sigdf
    next 
  }
  sigdf[,2] <- ifelse(sigdf[,2]=="enriched",1,-1)
  bidirectsigs[[sig]] <- sigdf
}
bidirectsigs
$CellAge

$CSgene
  [1] "TP53"       "TERF2"      "MAPK14"     "CDKN2A"     "CDKN1A"     "CCNE1"      "CCNA1"      "MAPKAPK5"   "CBX4"       "TXN"       
 [11] "TBX2"       "STAT3"      "SRF"        "BMI1"       "MAP2K4"     "MAP2K6"     "MAP2K3"     "MAPK8"      "MAPK3"      "MAPK1"     
 [21] "PRKCD"      "PML"        "OPA1"       "ATM"        "MDM2"       "CXCL8"      "IL6"        "IGFBP7"     "ID1"        "HRAS"      
 [31] "H2AFX"      "POT1"       "SIRT1"      "KDM6B"      "PLA2R1"     "EZH2"       "E2F3"       "E2F1"       "CEBPB"      "CDKN2D"    
 [41] "CDKN2B"     "CDKN1B"     "CDK6"       "CDK4"       "CDK2"       "CDC42"      "RBX1"       "CDC27"      "CDK1"       "MAML1"     
 [51] "CD44"       "MAD2L1BP"   "MAP4K4"     "AIM2"       "RECQL4"     "ARHGAP18"   "KL"         "MAPKAPK2"   "AURKB"      "SLC16A7"   
 [61] "CCNE2"      "HIST1H2BJ"  "HIST1H3F"   "CCNA2"      "MCM3AP"     "CDC16"      "TSC22D1"    "CBS"        "TNFSF13"    "CTNNAL1"   
 [71] "EED"        "PNPT1"      "CDC23"      "RNASET2"    "TP63"       "CAV1"       "MKNK1"      "TSLP"       "HIST1H2BK"  "PPM1D"     
 [81] "HAVCR2"     "CBX2"       "KDM2B"      "DPY30"      "C2orf40"    "YPEL3"      "HIST2H4A"   "HIST1H4L"   "HIST1H4E"   "HIST1H4B"  
 [91] "HIST1H4H"   "HIST1H4C"   "HIST1H4J"   "HIST1H4K"   "HIST1H4F"   "HIST1H4D"   "HIST1H4A"   "HIST1H3B"   "HIST1H3H"   "HIST1H3J"  
[101] "HIST1H3G"   "HIST1H3I"   "HIST1H3E"   "HIST1H3C"   "HIST1H3D"   "HIST1H3A"   "HIST2H2BE"  "HIST1H2BO"  "HIST1H2BC"  "HIST1H2BI" 
[111] "HIST1H2BH"  "HIST1H2BE"  "HIST1H2BF"  "HIST1H2BM"  "HIST1H2BN"  "HIST1H2BL"  "HIST1H2BG"  "HIST2H2AC"  "HIST2H2AA3" "HIST1H2AB" 
[121] "HIST1H2AC"  "HIST1H2AJ"  "HIST1H4I"   "HIST3H3"    "CALR"       "HMGA2"      "PHC3"       "KAT6A"      "EHMT1"      "SMC6"      
[131] "AIMP2"      "CALCA"      "DEK"        "MAPKAPK3"   "ZNF148"     "YY1"        "WRN"        "WNT5A"      "NR1H2"      "UBE3A"     
[141] "UBE2E1"     "UBE2D1"     "UBC"        "UBB"        "UBA52"      "CDC26P1"    "TYMS"       "TWIST1"     "HIRA"       "RPS27AP11" 
[151] "HIST2H2AA4" "TP73"       "TOP 1,00"   "TNF"        "TGFB2"      "TGFB1"      "TFDP1"      "TERT"       "TERF1"      "BUB1B"     
[161] "BUB1"       "TCF3"       "TBX3"       "TAGLN"      "STAT6"      "STAT1"      "BRAF"       "SREBF1"     "BRCA1"      "SP1"       
[171] "SOX5"       "SOD2"       "SNAI1"      "SMARCB1"    "SMARCA2"    "HIST2H3D"   "PHC1P1"     "ACD"        "SKIL"       "LOC649620" 
[181] "SLC13A3"    "LOC647654"  "SMURF2"     "ANAPC1"     "SHC1"       "CPEB1"      "H3F3AP6"    "ZMAT3"      "RBBP4P1"    "SRSF3"     
[191] "SRSF1"      "SATB1"      "S100A6"     "RXRB"       "RRM2"       "RRM1"       "RPS27A"     "RPS6KA3"    "RPS6KA2"    "RPS6KA1"   
[201] "RPL5"       "RNF2"       "RIT1"       "RING1"      "BCL2L1"     "RELA"       "BCL2"       "CCND1"      "RBP2"       "RBL2"      
[211] "RBL1"       "RBBP7"      "RBBP4"      "NTN4"       "RB1"        "IL21"       "RAN"        "RAF1"       "RAC1"       "TNRC6C"    
[221] "KIAA1524"   "EP400"      "CNOT6"      "CBX8"       "PTEN"       "SEPN1"      "BACH1"      "PSMB5"      "PROX1"      "PRL"       
[231] "MAP2K7"     "MAP2K1"     "MAPK10"     "MAPK9"      "MAPK11"     "MAPK7"      "PRKDC"      "RNF114"     "PRKCI"      "ATF7IP"    
[241] "MFN1"       "PRKAA2"     "CDKN2AIP"   "RBM38"      "PRG2"       "HIST2H4B"   "HJURP"      "TMEM140"    "PBRM1"      "Mar-05"    
[251] "PPARG"      "PPARD"      "POU2F1"     "TERF2IP"    "ERRFI1"     "H2BFS"      "PLK1"       "PLAUR"      "PIN1"       "PIM1"      
[261] "PIK3CA"     "PHB"        "PGR"        "PGD"        "PIAS4"      "PDGFB"      "SIRT6"      "ANAPC11"    "ANAPC7"     "ANAPC5"    
[271] "WNT16"      "FZR1"       "ZBTB7A"     "ERGIC2"     "PCNA"       "FIS1"       "PAX3"       "NOX4"       "MINK1"      "PEBP1"     
[281] "YBX1"       "NINJ1"      "NFKB1"      "H2AFB1"     "NDN"        "NCAM1"      "NBN"        "MYC"        "MYBL2"      "MSN"       
[291] "ASS1"       "LOC441488"  "MRE11A"     "MOV10"      "MMP7"       "MIF"        "MAP3K5"     "MAP3K1"     "MECP2"      "MCL1"      
[301] "MAGEA2"     "SMAD9"      "SMAD7"      "SMAD6"      "SMAD5"      "SMAD4"      "SMAD3"      "SMAD2"      "SMAD1"      "MAD2L1"    
[311] "MXD1"       "MIR34A"     "MIR30A"     "MIR299"     "MIR29A"     "MIR22"      "MIR217"     "MIR21"      "MIR205"     "MIR203A"   
[321] "MIR191"     "MIR146A"    "MIR141"     "MIR10B"     "ARNTL"      "LMNB1"      "LMNA"       "LGALS9"     "RHOA"       "KRT5"      
[331] "KRAS"       "KIT"        "KIR2DL4"    "KCNJ12"     "JUN"        "JAK2"       "ITGB4"      "IRS1"       "IRF7"       "IRF5"      
[341] "IRF3"       "ING1"       "IDO1"       "ILF3"       "IL15"       "IL12B"      "CXCR2"      "IL4"        "IGFBP5"     "IGFBP3"    
[351] "IGFBP1"     "IGF1R"      "IGF1"       "H3F3AP5"    "IFNG"       "IFI16"      "IDH1"       "ID2"        "HIST2H3A"   "BIRC5"     
[361] "HSPB1"      "HSPA9"      "HSPA5"      "HSPA1A"     "APEX1"      "HNRNPA1"    "FOXA3"      "FOXA2"      "FOXA1"      "HMGA1"     
[371] "HIF1A"      "ANXA5"      "HELLS"      "HDAC1"      "H3F3B"      "H3F3A"      "HIST1H2BB"  "HIST1H2BD"  "H2AFZ"      "HIST1H2AD" 
[381] "HIST1H2AE"  "ANAPC4"     "ANAPC2"     "UBN1"       "SENP1"      "GUCY2C"     "GSK3B"      "UHRF1"      "BRD7"       "NSMCE2"    
[391] "PTRF"       "GPI"        "GNAO1"      "RPS6KA6"    "TNRC6A"     "AGO2"       "B3GAT1"     "DNAJC2"     "GJA1"       "AGO1"      
[401] "EHF"        "TINF2"      "LDLRAP1"    "ULK3"       "GAPDH"      "ABI3BP"     "ASF1A"      "HIST1H2BA"  "G6PD"       "ACKR1"     
[411] "MTOR"       "CDC26"      "CNOT6L"     "FOS"        "CABIN1"     "MORC3"      "SUZ12"      "NPTXR"      "CBX6"       "SIRT3"     
[421] "CRTC1"      "PPP1R13B"   "SUN1"       "SMC5"       "TNRC6B"     "FOXO1"      "FOXM1"      "TNIK"       "SCMH1"      "DKK 1,00"  
[431] "FGFR2"      "FGF2"       "HEPACAM"    "FANCD2"     "EWSR1"      "ETS2"       "ETS1"       "ESR2"       "ERF"        "AKT1"      
[441] "EREG"       "ERBB2"      "ENG"        "ELN"        "CRTC2"      "EIF5A"      "EGR1"       "EGFR"       "EEF1B2"     "AGO4"      
[451] "AGO3"       "EEF1A1"     "PHC2"       "PHC1"       "ABCA1"      "E2F2"       "DUSP6"      "DUSP4"      "HBEGF"      "AGT"       
[461] "DNMT3A"     "AGER"       "DKC1"       "DAXX"       "CYP3A4"     "CTSZ"       "CTSD"       "CSNK2A1"    "E2F7"       "PARP1"     
[471] "HIST3H2BB"  "HIST2H3C"   "JDP2"       "HIST4H4"    "CLU"        "CKB"        "RASSF1"     "CHEK1"      "TOPBP1"     "UBE2C"     
[481] "KIF2C"      "BTG3"       "EHMT2"      "GADD45G"    "NEK6"       "ZMYND11"    "SPINT2"     "CENPA"      "AGR2"       "CEBPG"     
[491] "HYOU1"      "TADA3"      "MCRS1"      "NDRG1"      "ANAPC10"    "CDKN2C"     "ZMPSTE24"   "PSMD14"     "NAMPT"      "RAD50"     
[501] "TRIM10"     "DNM1L"      "BCL2L11"   

$GOBP_CELLULAR_SENESCENCE
  [1] "AKT3"     "MIR543"   "CDK2"     "CDK6"     "CDKN1A"   "ZMPSTE24" "CDKN1B"   "CDKN2A"   "CDKN2B"   "CITED2"   "KAT5"     "PLK2"    
 [13] "NEK6"     "ZNF277"   "CGAS"     "COMP"     "MAPK14"   "VASH1"    "PLA2R1"   "SMC5"     "SIRT1"    "MORC3"    "NUP62"    "ABL1"    
 [25] "ULK3"     "RSL1D1"   "FBXO5"    "FBXO4"    "MAGEA2B"  "NSMCE2"   "H2AX"     "HLA-G"    "HMGA1"    "HRAS"     "ID2"      "IGF1R"   
 [37] "ING2"     "KIR2DL4"  "ARG2"     "LMNA"     "BMAL1"    "MIR10A"   "MIR146A"  "MIR17"    "MIR188"   "MIR217"   "MIR22"    "MIR34A"  
 [49] "MAGEA2"   "MAP3K3"   "MAP3K5"   "MIF"      "MNT"      "ATM"      "NPM1"     "YBX1"     "OPA1"     "PAWR"     "ABI3"     "FZR1"    
 [61] "WNT16"    "SIRT6"    "PML"      "PRMT6"    "PRELP"    "PRKCD"    "MAPK8"    "MAPK11"   "MAPK9"    "MAPK10"   "MAP2K1"   "MAP2K3"  
 [73] "MAP2K6"   "MAP2K7"   "B2M"      "ZMIZ1"    "PTEN"     "MIR20B"   "RBL1"     "BCL6"     "MAP2K4"   "BMPR1A"   "SPI1"     "SRF"     
 [85] "BRCA2"    "NEK4"     "TBX2"     "TBX3"     "MIR590"   "TERC"     "TERF2"    "TERT"     "TOP2B"    "TP53"     "TWIST1"   "WNT1"    
 [97] "WRN"      "SMC6"     "KAT6A"    "ZKSCAN3"  "HMGA2"    "CALR"     "YPEL3"    "ECRG4"    "MAPKAPK5" "TP63"     "PNPT1"    "DNAJA3"  
[109] "EEF1E1"   "NUAK1"   

$GOBP_NEGATIVE_REGULATION_OF_CELLULAR_SENESCENCE

$GOBP_POSITIVE_REGULATION_OF_CELLULAR_SENESCENCE

$HernandezSegura

$REACTOME_CELLULAR_SENESCENCE
  [1] "CDC27"    "E2F2"     "SCMH1"    "MRE11"    "MAP2K3"   "MAPK9"    "ANAPC4"   "MAP2K4"   "MAP4K4"   "RPS6KA2"  "UBE2D1"   "EED"     
 [13] "MAP2K7"   "TNRC6C"   "MAPKAPK5" "ANAPC5"   "TNRC6A"   "TINF2"    "AGO1"     "CDC23"    "CABIN1"   "MAPK1"    "HIRA"     "TNRC6B"  
 [25] "E2F1"     "RBBP7"    "MAPK3"    "ACD"      "NBN"      "CCNE1"    "FZR1"     "ERF"      "CDK6"     "H2AZ2"    "EZH2"     "MAPK8"   
 [37] "UBE2S"    "MAP2K6"   "NFKB1"    "MAPK10"   "ANAPC15"  "CDKN1B"   "PHC1"     "ASF1A"    "MAPK14"   "E2F3"     "LMNB1"    "RAD50"   
 [49] "TFDP2"    "MAPKAPK3" "IL1A"     "RPS6KA1"  "UBN1"     "RNF2"     "CDKN2C"   "CDK2"     "H1-3"     "H1-1"     "H2BC11"   "CDKN1A"  
 [61] "ID1"      "AGO3"     "POT1"     "CDKN2D"   "CDC16"    "H3-3B"    "KDM6B"    "TERF2"    "CCNA1"    "PHC2"     "AGO4"     "ETS1"    
 [73] "CDK4"     "MDM2"     "IL6"      "TXN"      "HMGA1"    "RB1"      "MINK1"    "TP53"     "ANAPC11"  "CBX8"     "CBX4"     "RPS27A"  
 [85] "CCNA2"    "H2BC1"    "TERF1"    "CDKN2B"   "CDKN2A"   "ATM"      "HMGA2"    "UBC"      "VENTX"    "ANAPC1"   "TNIK"     "MOV10"   
 [97] "ETS2"     "H2BC5"    "H4C8"     "RBBP4"    "MAPKAPK2" "H3-3A"    "IGFBP7"   "ANAPC10"  "ANAPC16"  "MAPK7"    "TERF2IP"  "H3-4"    
[109] "BMI1"     "H1-4"     "STAT3"    "CXCL8"    "UBE2E1"   "UBB"      "FOS"      "IFNB1"    "CEBPB"    "KAT5"     "RELA"     "PHC3"    
[121] "CBX2"     "UBE2C"    "CCNE2"    "ANAPC2"   "CDC26"    "RPS6KA3"  "JUN"      "SUZ12"    "H2AC6"    "H2BC4"    "EHMT1"    "EP400"   
[133] "H3C13"    "CBX6"     "H2AC20"   "H1-5"     "H2BC21"   "H2BC13"   "MAPK11"   "SP1"      "H1-2"     "H2AX"     "H1-0"     "ANAPC7"  
[145] "H2AC7"    "H2BC26"   "H4C3"     "H3C12"    "H4C11"    "H3C4"     "MAP3K5"   "H4C16"    "H2BC12"   "TFDP1"    "MDM4"     "H3C14"   
[157] "H3C15"    "RING1"    "EHMT2"    "UBA52"    "H2AJ"     "H4C15"    "H4C14"    "H4C12"    "H2BC14"   "H2BC8"    "H3C8"     "H2AB1"   
[169] "H2BC6"    "H4C6"     "H2BC17"   "H3C6"     "H4C13"    "H3C11"    "H2BC9"    "H3C1"     "H4C9"     "H2AC14"   "H2BC3"    "H4C5"    
[181] "H2AC8"    "H4C4"     "H2BC7"    "H3C7"     "H2AC4"    "H2BC10"   "H4C1"     "H4C2"     "H3C10"    "MIR24-2"  "MIR24-1"  "H3C2"    
[193] "H3C3"     "H2AC18"   "H2AC19"  

$SAUL_SEN_MAYO

$SeneQuest
NA
df_logmedian <- CalculateScores(data = corrcounts_merge, metadata = metadata_merge, method = "logmedian", gene_sets = bidirectsigs)
Considering bidirectional gene signature mode for signature CellAge
Considering unidirectional gene signature mode for signature CSgene
Considering unidirectional gene signature mode for signature GOBP_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_NEGATIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_POSITIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering bidirectional gene signature mode for signature HernandezSegura
Considering unidirectional gene signature mode for signature REACTOME_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature SAUL_SEN_MAYO
Considering bidirectional gene signature mode for signature SeneQuest
senescence_triggers_colors <- c(
  "none" = "#E57373",  # Soft red  
  "Radiation" = "#BDBDBD",  # Medium gray  
  "DNA damage" = "#64B5F6",  # Brighter blue  
  "Telomere shortening" = "#4FC3F7",  # Vivid sky blue  
  "DNA demethylation" = "#BA68C8",  # Rich lavender  
  "Oxidative stress" = "#FDD835",  # Strong yellow  
  "Conditioned Medium" = "#F2994A",  # Warm orange  
  "Oncogene" = "#81C784",  # Medium green  
  "Lipid Accumulation" = "#E57373",  # Coral  
  "Calcium influx" = "#26A69A",  # Deep teal  
  "Plasma membrane dysruption" = "#D32F2F",  # Strong salmon  
  "OSKM factors" = "#FFB74D",  # Bright peach  
  "YAP KO" = "#9575CD"  # Deep pastel purple  
)

cellTypes_colors <- c(
  "Fibroblast" = "#FF6961",   # Strong Pastel Red  
  "Keratinocyte" = "#FFB347", # Strong Pastel Orange  
  "Melanocyte" = "#FFD700",   # Strong Pastel Yellow  
  "Endothelial" = "#77DD77",  # Strong Pastel Green  
  "Neuronal" = "#779ECB",     # Strong Pastel Blue  
  "Mesenchymal" = "#C27BA0"   # Strong Pastel Purple  
)

cond_cohend <- list(A=c("Senescent"), # if no variable is defined, will be the first that appears in the ggplot
                    B=c("Proliferative","Quiescent"))

PlotScores(ResultsList = df_logmedian, ColorVariable = "CellType", GroupingVariable="Condition",  method ="logmedian", ColorValues = cellTypes_colors, ConnectGroups=TRUE, ncol = 3, nrow = 3, widthTitle=20, y_limits = NULL, legend_nrow = 2,xlab=NULL, cond_cohend = cond_cohend)

 
df_ssgsea <- CalculateScores(data = corrcounts_merge, metadata = metadata_merge, method = "ssGSEA", gene_sets = bidirectsigs)
Considering bidirectional gene signature mode for signature CellAge
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature CSgene
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature GOBP_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature GOBP_NEGATIVE_REGULATION_OF_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature GOBP_POSITIVE_REGULATION_OF_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering bidirectional gene signature mode for signature HernandezSegura
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature REACTOME_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature SAUL_SEN_MAYO
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering bidirectional gene signature mode for signature SeneQuest
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
senescence_triggers_colors <- c(
  "none" = "#E57373",  # Soft red  
  "Radiation" = "#BDBDBD",  # Medium gray  
  "DNA damage" = "#64B5F6",  # Brighter blue  
  "Telomere shortening" = "#4FC3F7",  # Vivid sky blue  
  "DNA demethylation" = "#BA68C8",  # Rich lavender  
  "Oxidative stress" = "#FDD835",  # Strong yellow  
  "Conditioned Medium" = "#F2994A",  # Warm orange  
  "Oncogene" = "#81C784",  # Medium green  
  "Lipid Accumulation" = "#E57373",  # Coral  
  "Calcium influx" = "#26A69A",  # Deep teal  
  "Plasma membrane dysruption" = "#D32F2F",  # Strong salmon  
  "OSKM factors" = "#FFB74D",  # Bright peach  
  "YAP KO" = "#9575CD"  # Deep pastel purple  
)

cellTypes_colors <- c(
  "Fibroblast" = "#FF6961",   # Strong Pastel Red  
  "Keratinocyte" = "#FFB347", # Strong Pastel Orange  
  "Melanocyte" = "#FFD700",   # Strong Pastel Yellow  
  "Endothelial" = "#77DD77",  # Strong Pastel Green  
  "Neuronal" = "#779ECB",     # Strong Pastel Blue  
  "Mesenchymal" = "#C27BA0"   # Strong Pastel Purple  
)

cond_cohend <- list(A=c("Senescent"), # if no variable is defined, will be the first that appears in the ggplot
                    B=c("Proliferative","Quiescent"))

PlotScores(ResultsList = df_ssgsea, ColorVariable = "CellType", GroupingVariable="Condition",  method ="ssGSEA", ColorValues = cellTypes_colors, ConnectGroups=TRUE, ncol = 3, nrow = 3, widthTitle=20, y_limits = NULL, legend_nrow = 2,xlab=NULL, cond_cohend = cond_cohend)

 
df_ranking <- CalculateScores(data = corrcounts_merge, metadata = metadata_merge, method = "ranking", gene_sets = bidirectsigs)
Considering bidirectional gene signature mode for signature CellAge
Considering unidirectional gene signature mode for signature CSgene
Considering unidirectional gene signature mode for signature GOBP_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_NEGATIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_POSITIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering bidirectional gene signature mode for signature HernandezSegura
Considering unidirectional gene signature mode for signature REACTOME_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature SAUL_SEN_MAYO
Considering bidirectional gene signature mode for signature SeneQuest
senescence_triggers_colors <- c(
  "none" = "#E57373",  # Soft red  
  "Radiation" = "#BDBDBD",  # Medium gray  
  "DNA damage" = "#64B5F6",  # Brighter blue  
  "Telomere shortening" = "#4FC3F7",  # Vivid sky blue  
  "DNA demethylation" = "#BA68C8",  # Rich lavender  
  "Oxidative stress" = "#FDD835",  # Strong yellow  
  "Conditioned Medium" = "#F2994A",  # Warm orange  
  "Oncogene" = "#81C784",  # Medium green  
  "Lipid Accumulation" = "#E57373",  # Coral  
  "Calcium influx" = "#26A69A",  # Deep teal  
  "Plasma membrane dysruption" = "#D32F2F",  # Strong salmon  
  "OSKM factors" = "#FFB74D",  # Bright peach  
  "YAP KO" = "#9575CD"  # Deep pastel purple  
)

cellTypes_colors <- c(
  "Fibroblast" = "#FF6961",   # Strong Pastel Red  
  "Keratinocyte" = "#FFB347", # Strong Pastel Orange  
  "Melanocyte" = "#FFD700",   # Strong Pastel Yellow  
  "Endothelial" = "#77DD77",  # Strong Pastel Green  
  "Neuronal" = "#779ECB",     # Strong Pastel Blue  
  "Mesenchymal" = "#C27BA0"   # Strong Pastel Purple  
)

cond_cohend <- list(A=c("Senescent"), # if no variable is defined, will be the first that appears in the ggplot
                    B=c("Proliferative","Quiescent"))

PlotScores(ResultsList = df_ranking, ColorVariable = "CellType", GroupingVariable="Condition",  method ="ranking", ColorValues = cellTypes_colors, ConnectGroups=TRUE, ncol = 3, nrow = 3, widthTitle=20, y_limits = NULL, legend_nrow = 2,xlab=NULL, cond_cohend = cond_cohend)

Heatmap for Cohen’s D

PlotScores(data = corrcounts_merge, 
           metadata = metadata_merge,  
           gene_sets=bidirectsigs, 
           GroupingVariable="Condition",  
           method ="all",   
           ncol = NULL, 
           nrow = NULL, 
           widthTitle=30, 
           limits = NULL,   
           title="Marthandan et al. 2016", 
           titlesize = 12,
           ColorValues = NULL)  
Considering bidirectional gene signature mode for signature CellAge
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature CSgene
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature GOBP_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature GOBP_NEGATIVE_REGULATION_OF_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature GOBP_POSITIVE_REGULATION_OF_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering bidirectional gene signature mode for signature HernandezSegura
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature REACTOME_CELLULAR_SENESCENCE
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering unidirectional gene signature mode for signature SAUL_SEN_MAYO
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering bidirectional gene signature mode for signature SeneQuest
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = FALSE.
No id variables; using all as measure variables
Considering bidirectional gene signature mode for signature CellAge
Considering unidirectional gene signature mode for signature CSgene
Considering unidirectional gene signature mode for signature GOBP_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_NEGATIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_POSITIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering bidirectional gene signature mode for signature HernandezSegura
Considering unidirectional gene signature mode for signature REACTOME_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature SAUL_SEN_MAYO
Considering bidirectional gene signature mode for signature SeneQuest
Considering bidirectional gene signature mode for signature CellAge
Considering unidirectional gene signature mode for signature CSgene
Considering unidirectional gene signature mode for signature GOBP_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_NEGATIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature GOBP_POSITIVE_REGULATION_OF_CELLULAR_SENESCENCE
Considering bidirectional gene signature mode for signature HernandezSegura
Considering unidirectional gene signature mode for signature REACTOME_CELLULAR_SENESCENCE
Considering unidirectional gene signature mode for signature SAUL_SEN_MAYO
Considering bidirectional gene signature mode for signature SeneQuest

Individual Genes

Violin Expression Plots

IndividualGenes_Violins(data = corrcounts_merge, metadata = metadata_merge, genes = c("CDKN1A", "CDKN2A", "GLB1","TP53","CCL2"), GroupingVariable = "Condition", plot=T, ncol=NULL, nrow=2, divide="CellType", invert_divide=FALSE,ColorValues=senescence_triggers_colors, pointSize=2, ColorVariable="SenescentType", title="Senescence", widthTitle=16,y_limits = NULL,legend_nrow=4, xlab="Condition",colorlab="") 
Using gene as id variables

Correlation Heatmap

CorrelationHeatmap(data=corrcounts_merge, 
                   metadata = metadata_merge, 
                   genes=c("CDKN1A", "CDKN2A", "GLB1","TP53","CCL2"), 
                   separate.by = "Condition", 
                   method = "pearson",  
                   colorlist = list(low = "#3F4193", mid = "#F9F4AE", high = "#B44141"),
                   limits_colorscale = c(-1,0,1), 
                   widthTitle = 16, 
                   title = "test", 
                   cluster_rows = TRUE, 
                   cluster_columns = TRUE,  
                   detailedresults = FALSE, 
                   legend_position="right",
                   titlesize=20)
Warning: Heatmap/annotation names are duplicated: pearson's coefficient
Warning: Heatmap/annotation names are duplicated: pearson's coefficient, pearson's coefficient
Warning: `legend_height` you specified is too small, use the default minimal height.
Warning: `legend_height` you specified is too small, use the default minimal height.
Warning: `legend_height` you specified is too small, use the default minimal height.

Expression Heatmaps

ROC/AUC

Cohen’s d

PCA with genes from signature only

LS0tCnRpdGxlOiAiRGVidWdnaW5nIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIEltcG9ydCBEYXRhCgpgYGB7cn0KY29ycmNvdW50c19tZXJnZSA8LSByZWFkUkRTKCJ+L1ZlcnNpb25Db250cm9sL3NlbmVzY2VuY2VfYmVuY2htYXJraW5nL0RhdGEvY29ycmNvdW50c19tZXJnZS5yZHMiKQptZXRhZGF0YV9tZXJnZSA8LSByZWFkUkRTKCJ+L1ZlcnNpb25Db250cm9sL3NlbmVzY2VuY2VfYmVuY2htYXJraW5nL0RhdGEvbWV0YWRhdGFfbWVyZ2UucmRzIikKU2VuZXNjZW5jZVNpZ25hdHVyZXMgPC0gcmVhZFJEUygifi9WZXJzaW9uQ29udHJvbC9zZW5lc2NlbmNlX2JlbmNobWFya2luZy9Db21tb25GaWxlcy9TZW5lc2NlbmNlU2lnbmF0dXJlc19kaXZpZGVkX25ld0NlbGxBZ2UuUkRTIikKYGBgCgpgYGB7cn0KbGlicmFyeShtYXJrZVIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ3B1YnIpCmxpYnJhcnkoZWRnZVIpCj9tYXJrZVIKYGBgCgojIFNjb3JlcyAKCmBgYHtyfQo/Q2FsY3VsYXRlU2NvcmVzCmBgYAoKIyMgVW5pZGlyZWN0aW9uYWwKYGBge3IgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTZ9CmRmX3NzR1NFQSA8LSBDYWxjdWxhdGVTY29yZXMoZGF0YSA9IGNvcnJjb3VudHNfbWVyZ2UsIG1ldGFkYXRhID0gbWV0YWRhdGFfbWVyZ2UsIG1ldGhvZCA9ICJzc0dTRUEiLCBnZW5lX3NldHMgPSBTZW5lc2NlbmNlU2lnbmF0dXJlcykKCnNlbmVzY2VuY2VfdHJpZ2dlcnNfY29sb3JzIDwtIGMoCiAgIm5vbmUiID0gIiNFNTczNzMiLCAgIyBTb2Z0IHJlZCAgCiAgIlJhZGlhdGlvbiIgPSAiI0JEQkRCRCIsICAjIE1lZGl1bSBncmF5ICAKICAiRE5BIGRhbWFnZSIgPSAiIzY0QjVGNiIsICAjIEJyaWdodGVyIGJsdWUgIAogICJUZWxvbWVyZSBzaG9ydGVuaW5nIiA9ICIjNEZDM0Y3IiwgICMgVml2aWQgc2t5IGJsdWUgIAogICJETkEgZGVtZXRoeWxhdGlvbiIgPSAiI0JBNjhDOCIsICAjIFJpY2ggbGF2ZW5kZXIgIAogICJPeGlkYXRpdmUgc3RyZXNzIiA9ICIjRkREODM1IiwgICMgU3Ryb25nIHllbGxvdyAgCiAgIkNvbmRpdGlvbmVkIE1lZGl1bSIgPSAiI0YyOTk0QSIsICAjIFdhcm0gb3JhbmdlICAKICAiT25jb2dlbmUiID0gIiM4MUM3ODQiLCAgIyBNZWRpdW0gZ3JlZW4gIAogICJMaXBpZCBBY2N1bXVsYXRpb24iID0gIiNFNTczNzMiLCAgIyBDb3JhbCAgCiAgIkNhbGNpdW0gaW5mbHV4IiA9ICIjMjZBNjlBIiwgICMgRGVlcCB0ZWFsICAKICAiUGxhc21hIG1lbWJyYW5lIGR5c3J1cHRpb24iID0gIiNEMzJGMkYiLCAgIyBTdHJvbmcgc2FsbW9uICAKICAiT1NLTSBmYWN0b3JzIiA9ICIjRkZCNzREIiwgICMgQnJpZ2h0IHBlYWNoICAKICAiWUFQIEtPIiA9ICIjOTU3NUNEIiAgIyBEZWVwIHBhc3RlbCBwdXJwbGUgIAopCgpjZWxsVHlwZXNfY29sb3JzIDwtIGMoCiAgIkZpYnJvYmxhc3QiID0gIiNGRjY5NjEiLCAgICMgU3Ryb25nIFBhc3RlbCBSZWQgIAogICJLZXJhdGlub2N5dGUiID0gIiNGRkIzNDciLCAjIFN0cm9uZyBQYXN0ZWwgT3JhbmdlICAKICAiTWVsYW5vY3l0ZSIgPSAiI0ZGRDcwMCIsICAgIyBTdHJvbmcgUGFzdGVsIFllbGxvdyAgCiAgIkVuZG90aGVsaWFsIiA9ICIjNzdERDc3IiwgICMgU3Ryb25nIFBhc3RlbCBHcmVlbiAgCiAgIk5ldXJvbmFsIiA9ICIjNzc5RUNCIiwgICAgICMgU3Ryb25nIFBhc3RlbCBCbHVlICAKICAiTWVzZW5jaHltYWwiID0gIiNDMjdCQTAiICAgIyBTdHJvbmcgUGFzdGVsIFB1cnBsZSAgCikKCmNvbmRfY29oZW5kIDwtIGxpc3QoQT1jKCJTZW5lc2NlbnQiKSwgIyBpZiBubyB2YXJpYWJsZSBpcyBkZWZpbmVkLCB3aWxsIGJlIHRoZSBmaXJzdCB0aGF0IGFwcGVhcnMgaW4gdGhlIGdncGxvdAogICAgICAgICAgICAgICAgICAgIEI9YygiUHJvbGlmZXJhdGl2ZSIsIlF1aWVzY2VudCIpKQoKUGxvdFNjb3JlcyhSZXN1bHRzTGlzdCA9IGRmX3NzR1NFQSwgQ29sb3JWYXJpYWJsZSA9ICJDZWxsVHlwZSIsIEdyb3VwaW5nVmFyaWFibGU9IkNvbmRpdGlvbiIsICBtZXRob2QgPSJzc0dTRUEiLCBDb2xvclZhbHVlcyA9IGNlbGxUeXBlc19jb2xvcnMsIENvbm5lY3RHcm91cHM9VFJVRSwgbmNvbCA9IDYsIG5yb3cgPSAyLCB3aWR0aFRpdGxlPTIwLCB5X2xpbWl0cyA9IE5VTEwsIGxlZ2VuZF9ucm93ID0gMixjb25kX2NvaGVuZD1jb25kX2NvaGVuZCkKCmBgYAoKYGBge3IgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTZ9CmRmX2xvZ21lZGlhbiA8LSBDYWxjdWxhdGVTY29yZXMoZGF0YSA9IGNvcnJjb3VudHNfbWVyZ2UsIG1ldGFkYXRhID0gbWV0YWRhdGFfbWVyZ2UsIG1ldGhvZCA9ICJsb2dtZWRpYW4iLCBnZW5lX3NldHMgPSBTZW5lc2NlbmNlU2lnbmF0dXJlcykKCnNlbmVzY2VuY2VfdHJpZ2dlcnNfY29sb3JzIDwtIGMoCiAgIm5vbmUiID0gIiNFNTczNzMiLCAgIyBTb2Z0IHJlZCAgCiAgIlJhZGlhdGlvbiIgPSAiI0JEQkRCRCIsICAjIE1lZGl1bSBncmF5ICAKICAiRE5BIGRhbWFnZSIgPSAiIzY0QjVGNiIsICAjIEJyaWdodGVyIGJsdWUgIAogICJUZWxvbWVyZSBzaG9ydGVuaW5nIiA9ICIjNEZDM0Y3IiwgICMgVml2aWQgc2t5IGJsdWUgIAogICJETkEgZGVtZXRoeWxhdGlvbiIgPSAiI0JBNjhDOCIsICAjIFJpY2ggbGF2ZW5kZXIgIAogICJPeGlkYXRpdmUgc3RyZXNzIiA9ICIjRkREODM1IiwgICMgU3Ryb25nIHllbGxvdyAgCiAgIkNvbmRpdGlvbmVkIE1lZGl1bSIgPSAiI0YyOTk0QSIsICAjIFdhcm0gb3JhbmdlICAKICAiT25jb2dlbmUiID0gIiM4MUM3ODQiLCAgIyBNZWRpdW0gZ3JlZW4gIAogICJMaXBpZCBBY2N1bXVsYXRpb24iID0gIiNFNTczNzMiLCAgIyBDb3JhbCAgCiAgIkNhbGNpdW0gaW5mbHV4IiA9ICIjMjZBNjlBIiwgICMgRGVlcCB0ZWFsICAKICAiUGxhc21hIG1lbWJyYW5lIGR5c3J1cHRpb24iID0gIiNEMzJGMkYiLCAgIyBTdHJvbmcgc2FsbW9uICAKICAiT1NLTSBmYWN0b3JzIiA9ICIjRkZCNzREIiwgICMgQnJpZ2h0IHBlYWNoICAKICAiWUFQIEtPIiA9ICIjOTU3NUNEIiAgIyBEZWVwIHBhc3RlbCBwdXJwbGUgIAopCgpjZWxsVHlwZXNfY29sb3JzIDwtIGMoCiAgIkZpYnJvYmxhc3QiID0gIiNGRjY5NjEiLCAgICMgU3Ryb25nIFBhc3RlbCBSZWQgIAogICJLZXJhdGlub2N5dGUiID0gIiNGRkIzNDciLCAjIFN0cm9uZyBQYXN0ZWwgT3JhbmdlICAKICAiTWVsYW5vY3l0ZSIgPSAiI0ZGRDcwMCIsICAgIyBTdHJvbmcgUGFzdGVsIFllbGxvdyAgCiAgIkVuZG90aGVsaWFsIiA9ICIjNzdERDc3IiwgICMgU3Ryb25nIFBhc3RlbCBHcmVlbiAgCiAgIk5ldXJvbmFsIiA9ICIjNzc5RUNCIiwgICAgICMgU3Ryb25nIFBhc3RlbCBCbHVlICAKICAiTWVzZW5jaHltYWwiID0gIiNDMjdCQTAiICAgIyBTdHJvbmcgUGFzdGVsIFB1cnBsZSAgCikKCmNvbmRfY29oZW5kIDwtIGxpc3QoQT1jKCJTZW5lc2NlbnQiKSwgIyBpZiBubyB2YXJpYWJsZSBpcyBkZWZpbmVkLCB3aWxsIGJlIHRoZSBmaXJzdCB0aGF0IGFwcGVhcnMgaW4gdGhlIGdncGxvdAogICAgICAgICAgICAgICAgICAgIEI9YygiUHJvbGlmZXJhdGl2ZSIsIlF1aWVzY2VudCIpKQoKUGxvdFNjb3JlcyhSZXN1bHRzTGlzdCA9IGRmX2xvZ21lZGlhbiwgQ29sb3JWYXJpYWJsZSA9ICJDZWxsVHlwZSIsIEdyb3VwaW5nVmFyaWFibGU9IkNvbmRpdGlvbiIsICBtZXRob2QgPSJsb2dtZWRpYW4iLCBDb2xvclZhbHVlcyA9IGNlbGxUeXBlc19jb2xvcnMsIENvbm5lY3RHcm91cHM9VFJVRSwgbmNvbCA9IDYsIG5yb3cgPSAyLCB3aWR0aFRpdGxlPTIwLCB5X2xpbWl0cyA9IE5VTEwsIGxlZ2VuZF9ucm93ID0gMix4bGFiPU5VTEwsIGNvbmRfY29oZW5kID0gY29uZF9jb2hlbmQpCgpgYGAKCmBgYHtyIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02fQpkZl9yYW5raW5nIDwtIENhbGN1bGF0ZVNjb3JlcyhkYXRhID0gY29ycmNvdW50c19tZXJnZSwgbWV0YWRhdGEgPSBtZXRhZGF0YV9tZXJnZSwgbWV0aG9kID0gInJhbmtpbmciLCBnZW5lX3NldHMgPSBTZW5lc2NlbmNlU2lnbmF0dXJlcykKCnNlbmVzY2VuY2VfdHJpZ2dlcnNfY29sb3JzIDwtIGMoCiAgIm5vbmUiID0gIiNFNTczNzMiLCAgIyBTb2Z0IHJlZCAgCiAgIlJhZGlhdGlvbiIgPSAiI0JEQkRCRCIsICAjIE1lZGl1bSBncmF5ICAKICAiRE5BIGRhbWFnZSIgPSAiIzY0QjVGNiIsICAjIEJyaWdodGVyIGJsdWUgIAogICJUZWxvbWVyZSBzaG9ydGVuaW5nIiA9ICIjNEZDM0Y3IiwgICMgVml2aWQgc2t5IGJsdWUgIAogICJETkEgZGVtZXRoeWxhdGlvbiIgPSAiI0JBNjhDOCIsICAjIFJpY2ggbGF2ZW5kZXIgIAogICJPeGlkYXRpdmUgc3RyZXNzIiA9ICIjRkREODM1IiwgICMgU3Ryb25nIHllbGxvdyAgCiAgIkNvbmRpdGlvbmVkIE1lZGl1bSIgPSAiI0YyOTk0QSIsICAjIFdhcm0gb3JhbmdlICAKICAiT25jb2dlbmUiID0gIiM4MUM3ODQiLCAgIyBNZWRpdW0gZ3JlZW4gIAogICJMaXBpZCBBY2N1bXVsYXRpb24iID0gIiNFNTczNzMiLCAgIyBDb3JhbCAgCiAgIkNhbGNpdW0gaW5mbHV4IiA9ICIjMjZBNjlBIiwgICMgRGVlcCB0ZWFsICAKICAiUGxhc21hIG1lbWJyYW5lIGR5c3J1cHRpb24iID0gIiNEMzJGMkYiLCAgIyBTdHJvbmcgc2FsbW9uICAKICAiT1NLTSBmYWN0b3JzIiA9ICIjRkZCNzREIiwgICMgQnJpZ2h0IHBlYWNoICAKICAiWUFQIEtPIiA9ICIjOTU3NUNEIiAgIyBEZWVwIHBhc3RlbCBwdXJwbGUgIAopCgpjZWxsVHlwZXNfY29sb3JzIDwtIGMoCiAgIkZpYnJvYmxhc3QiID0gIiNGRjY5NjEiLCAgICMgU3Ryb25nIFBhc3RlbCBSZWQgIAogICJLZXJhdGlub2N5dGUiID0gIiNGRkIzNDciLCAjIFN0cm9uZyBQYXN0ZWwgT3JhbmdlICAKICAiTWVsYW5vY3l0ZSIgPSAiI0ZGRDcwMCIsICAgIyBTdHJvbmcgUGFzdGVsIFllbGxvdyAgCiAgIkVuZG90aGVsaWFsIiA9ICIjNzdERDc3IiwgICMgU3Ryb25nIFBhc3RlbCBHcmVlbiAgCiAgIk5ldXJvbmFsIiA9ICIjNzc5RUNCIiwgICAgICMgU3Ryb25nIFBhc3RlbCBCbHVlICAKICAiTWVzZW5jaHltYWwiID0gIiNDMjdCQTAiICAgIyBTdHJvbmcgUGFzdGVsIFB1cnBsZSAgCikKCmNvbmRfY29oZW5kIDwtIGxpc3QoQT1jKCJTZW5lc2NlbnQiKSwgIyBpZiBubyB2YXJpYWJsZSBpcyBkZWZpbmVkLCB3aWxsIGJlIHRoZSBmaXJzdCB0aGF0IGFwcGVhcnMgaW4gdGhlIGdncGxvdAogICAgICAgICAgICAgICAgICAgIEI9YygiUHJvbGlmZXJhdGl2ZSIsIlF1aWVzY2VudCIpKQoKUGxvdFNjb3JlcyhSZXN1bHRzTGlzdCA9IGRmX3JhbmtpbmcsIENvbG9yVmFyaWFibGUgPSAiQ2VsbFR5cGUiLCBHcm91cGluZ1ZhcmlhYmxlPSJDb25kaXRpb24iLCAgbWV0aG9kID0icmFua2luZyIsIENvbG9yVmFsdWVzID0gY2VsbFR5cGVzX2NvbG9ycywgQ29ubmVjdEdyb3Vwcz1UUlVFLCBuY29sID0gNiwgbnJvdyA9IDIsIHdpZHRoVGl0bGU9MjAsIHlfbGltaXRzID0gTlVMTCwgbGVnZW5kX25yb3cgPSAyLHhsYWI9TlVMTCwgY29uZF9jb2hlbmQgPSBjb25kX2NvaGVuZCkKCmBgYAoKYGBge3J9CndyYXBfdGl0bGVfYXV4IDwtIGZ1bmN0aW9uKHRpdGxlLCB3aWR0aCA9IDMwKSB7CiAgaWYgKG5jaGFyKHRpdGxlKSA8PSB3aWR0aCkgewogICAgcmV0dXJuKHRpdGxlKSAgIyBObyBuZWVkIHRvIHdyYXAgaWYgaXQgZml0cwogIH0KICAKICB3cmFwcGVkX3RpdGxlIDwtICIiCiAgd2hpbGUgKG5jaGFyKHRpdGxlKSA+IHdpZHRoKSB7CiAgICAjIEZpbmQgcG9zaXRpb25zIG9mIGNhcGl0YWwgbGV0dGVycyBhbmQgc3ltYm9scyBuZWFyIHRoZSB3cmFwIHBvaW50CiAgICBjYXBpdGFsX3BvcyA8LSBncmVnZXhwcigiW0EtWl0iLCB0aXRsZSlbWzFdXQogICAgc3ltYm9sX3BvcyA8LSBncmVnZXhwcigiKF98LXw6KSIsIHRpdGxlKVtbMV1dCiAgICAKICAgICMgQ2hlY2sgZm9yIHN5bWJvbCBicmVha3Mgd2l0aGluIHRoZSBsYXN0IGZldyBjaGFyYWN0ZXJzICh3aWR0aCAtIDUgdG8gd2lkdGgpCiAgICB2YWxpZF9zeW1ib2xfYnJlYWtzIDwtIHN5bWJvbF9wb3Nbc3ltYm9sX3BvcyA+PSAod2lkdGggLSA1KSAmIHN5bWJvbF9wb3MgPD0gd2lkdGhdCiAgICAKICAgIGlmIChsZW5ndGgodmFsaWRfc3ltYm9sX2JyZWFrcykgPiAwKSB7CiAgICAgICMgSWYgYSBzdWl0YWJsZSBzeW1ib2wgaXMgZm91bmQsIGJyZWFrIGF0IHRoZSBmaXJzdCB2YWxpZCBzeW1ib2wKICAgICAgYnJlYWtfYXQgPC0gdmFsaWRfc3ltYm9sX2JyZWFrc1sxXQogICAgfSBlbHNlIHsKICAgICAgIyBJZiBubyBzdWl0YWJsZSBzeW1ib2wsIGxvb2sgZm9yIGNhcGl0YWwgbGV0dGVycyB3aXRoaW4gdGhlIHNhbWUgcmFuZ2UKICAgICAgdmFsaWRfY2FwaXRhbF9icmVha3MgPC0gY2FwaXRhbF9wb3NbY2FwaXRhbF9wb3MgPj0gKHdpZHRoIC0gNSkgJiBjYXBpdGFsX3BvcyA8PSB3aWR0aF0KICAgICAgCiAgICAgIGlmIChsZW5ndGgodmFsaWRfY2FwaXRhbF9icmVha3MpID4gMCkgewogICAgICAgICMgSWYgYSBjYXBpdGFsIGxldHRlciBpcyBmb3VuZCwgYnJlYWsganVzdCBiZWZvcmUgdGhlIGNhcGl0YWwgbGV0dGVyCiAgICAgICAgYnJlYWtfYXQgPC0gdmFsaWRfY2FwaXRhbF9icmVha3NbMV0gLSAxCiAgICAgIH0gZWxzZSB7CiAgICAgICAgIyBJZiBubyBzdWl0YWJsZSBzeW1ib2wgb3IgY2FwaXRhbCBsZXR0ZXIsIGJyZWFrIGF0IHdpZHRoCiAgICAgICAgYnJlYWtfYXQgPC0gd2lkdGgKICAgICAgfQogICAgfQogICAgCiAgICAjIEFwcGVuZCB0aGUgd3JhcHBlZCBsaW5lCiAgICB3cmFwcGVkX3RpdGxlIDwtIHBhc3RlMCh3cmFwcGVkX3RpdGxlLCBzdWJzdHIodGl0bGUsIDEsIGJyZWFrX2F0KSwgIlxuIikKICAgIAogICAgIyBVcGRhdGUgdGl0bGUgd2l0aCB0aGUgcmVtYWluaW5nIHRleHQgYWZ0ZXIgdGhlIGJyZWFrCiAgICB0aXRsZSA8LSBzdWJzdHIodGl0bGUsIGJyZWFrX2F0ICsgMSwgbmNoYXIodGl0bGUpKQogIH0KICAKICAjIEFkZCB0aGUgcmVtYWluaW5nIHBhcnQgb2YgdGhlIHRpdGxlCiAgd3JhcHBlZF90aXRsZSA8LSBwYXN0ZTAod3JhcHBlZF90aXRsZSwgdGl0bGUpCiAgCiAgcmV0dXJuKHdyYXBwZWRfdGl0bGUpCn0KYGBgCgoKYGBge3IgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTh9CgpwbG90bGlzdCA8LSBsaXN0KCkKCmZvciAoc2lnIGluIG5hbWVzKGRmX3NzR1NFQSkpewogIAogIGRmX3N1YnNldF9zc0dTRUEgPC0gZGZfc3NHU0VBW1tzaWddXQogIGRmX3N1YnNldF9sb2dtZWRpYW4gPC0gZGZfbG9nbWVkaWFuW1tzaWddXQogIAogIGRmX3N1YnNldF9tZXJnZSA8LSBtZXJnZShkZl9zdWJzZXRfc3NHU0VBLGRmX3N1YnNldF9sb2dtZWRpYW4sYnk9InNhbXBsZSIpCiAgCiAgIyBXcmFwIHRoZSBzaWduYXR1cmUgbmFtZSB1c2luZyB0aGUgaGVscGVyIGZ1bmN0aW9uCiAgd3JhcHBlZF90aXRsZSA8LSB3cmFwX3RpdGxlX2F1eChzaWcsIHdpZHRoID0gMjApICAKICAKICBwbG90bGlzdFtbc2lnXV0gPC0gZ2dwbG90Mjo6Z2dwbG90KGRmX3N1YnNldF9tZXJnZSwgYWVzKHg9c2NvcmUueCwgeT1zY29yZS55KSkgKwogICAgZ2VvbV9wb2ludChzaXplPTQsIGFscGhhPTAuOCwgZmlsbD0iZGFya2dyZXkiLCBzaGFwZT0yMSkgKwogICAgdGhlbWVfYncoKSArCiAgICB4bGFiKCJzc0dTRUEgRW5yaWNobWVudCBTY29yZSIpICsKICAgIHlsYWIoIk5vcm1hbGlzZWQgU2lnbmF0dXJlIFNjb3JlIikgKwogICAgZ2d0aXRsZSh3cmFwcGVkX3RpdGxlKSArCiAgICB0aGVtZShwbG90LnRpdGxlID0gZ2dwbG90Mjo6ZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplPTEwKSwKICAgICAgICAgIHBsb3Quc3VidGl0bGUgPSBnZ3Bsb3QyOjplbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSAKICAKfQoKZ2dwdWJyOjpnZ2FycmFuZ2UocGxvdGxpc3Q9cGxvdGxpc3QsIG5yb3c9MywgbmNvbD00LCBhbGlnbiA9ICJoIikKYGBgCgojIyBCaWRpcmVjdGlvbmFsIGdlbmUgc2lnbmF0dXJlcwoKVHJ5IHNjb3JlcyB3aXRoIGJpZGlyZWN0aW9uYWwgc2lnbmF0dXJlcwoKYGBge3J9CmJpZGlyZWN0c2lncyA8LSByZWFkUkRTKCJ+L1ZlcnNpb25Db250cm9sL3NlbmVzY2VuY2VfYmVuY2htYXJraW5nL0NvbW1vbkZpbGVzL1NlbmVzY2VuY2VTaWduYXR1cmVzX2NvbXBsZXRlX25ld0NlbGxBZ2UuUkRTIikKZm9yIChzaWcgaW4gbmFtZXMoYmlkaXJlY3RzaWdzKSl7CiAgc2lnZGYgPC0gYmlkaXJlY3RzaWdzW1tzaWddXQogIHNpZ2RmIDwtIHNpZ2RmWywxOjJdICMgcmVtb3ZlIHRoZSB0aGlyZCBjb2x1bW4sIGlmIGFwcGxpY2FibGUKICBpZihhbnkoc2lnZGZbLDJdPT0ibm90X3JlcG9ydGVkIikpewogICAgc2lnZGYgPC0gc2lnZGZbLDFdCiAgICBiaWRpcmVjdHNpZ3NbW3NpZ11dIDwtIHNpZ2RmCiAgICBuZXh0IAogIH0KICBzaWdkZlssMl0gPC0gaWZlbHNlKHNpZ2RmWywyXT09ImVucmljaGVkIiwxLC0xKQogIGJpZGlyZWN0c2lnc1tbc2lnXV0gPC0gc2lnZGYKfQpiaWRpcmVjdHNpZ3MKCmBgYAoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTB9CmRmX2xvZ21lZGlhbiA8LSBDYWxjdWxhdGVTY29yZXMoZGF0YSA9IGNvcnJjb3VudHNfbWVyZ2UsIG1ldGFkYXRhID0gbWV0YWRhdGFfbWVyZ2UsIG1ldGhvZCA9ICJsb2dtZWRpYW4iLCBnZW5lX3NldHMgPSBiaWRpcmVjdHNpZ3MpCgpzZW5lc2NlbmNlX3RyaWdnZXJzX2NvbG9ycyA8LSBjKAogICJub25lIiA9ICIjRTU3MzczIiwgICMgU29mdCByZWQgIAogICJSYWRpYXRpb24iID0gIiNCREJEQkQiLCAgIyBNZWRpdW0gZ3JheSAgCiAgIkROQSBkYW1hZ2UiID0gIiM2NEI1RjYiLCAgIyBCcmlnaHRlciBibHVlICAKICAiVGVsb21lcmUgc2hvcnRlbmluZyIgPSAiIzRGQzNGNyIsICAjIFZpdmlkIHNreSBibHVlICAKICAiRE5BIGRlbWV0aHlsYXRpb24iID0gIiNCQTY4QzgiLCAgIyBSaWNoIGxhdmVuZGVyICAKICAiT3hpZGF0aXZlIHN0cmVzcyIgPSAiI0ZERDgzNSIsICAjIFN0cm9uZyB5ZWxsb3cgIAogICJDb25kaXRpb25lZCBNZWRpdW0iID0gIiNGMjk5NEEiLCAgIyBXYXJtIG9yYW5nZSAgCiAgIk9uY29nZW5lIiA9ICIjODFDNzg0IiwgICMgTWVkaXVtIGdyZWVuICAKICAiTGlwaWQgQWNjdW11bGF0aW9uIiA9ICIjRTU3MzczIiwgICMgQ29yYWwgIAogICJDYWxjaXVtIGluZmx1eCIgPSAiIzI2QTY5QSIsICAjIERlZXAgdGVhbCAgCiAgIlBsYXNtYSBtZW1icmFuZSBkeXNydXB0aW9uIiA9ICIjRDMyRjJGIiwgICMgU3Ryb25nIHNhbG1vbiAgCiAgIk9TS00gZmFjdG9ycyIgPSAiI0ZGQjc0RCIsICAjIEJyaWdodCBwZWFjaCAgCiAgIllBUCBLTyIgPSAiIzk1NzVDRCIgICMgRGVlcCBwYXN0ZWwgcHVycGxlICAKKQoKY2VsbFR5cGVzX2NvbG9ycyA8LSBjKAogICJGaWJyb2JsYXN0IiA9ICIjRkY2OTYxIiwgICAjIFN0cm9uZyBQYXN0ZWwgUmVkICAKICAiS2VyYXRpbm9jeXRlIiA9ICIjRkZCMzQ3IiwgIyBTdHJvbmcgUGFzdGVsIE9yYW5nZSAgCiAgIk1lbGFub2N5dGUiID0gIiNGRkQ3MDAiLCAgICMgU3Ryb25nIFBhc3RlbCBZZWxsb3cgIAogICJFbmRvdGhlbGlhbCIgPSAiIzc3REQ3NyIsICAjIFN0cm9uZyBQYXN0ZWwgR3JlZW4gIAogICJOZXVyb25hbCIgPSAiIzc3OUVDQiIsICAgICAjIFN0cm9uZyBQYXN0ZWwgQmx1ZSAgCiAgIk1lc2VuY2h5bWFsIiA9ICIjQzI3QkEwIiAgICMgU3Ryb25nIFBhc3RlbCBQdXJwbGUgIAopCgpjb25kX2NvaGVuZCA8LSBsaXN0KEE9YygiU2VuZXNjZW50IiksICMgaWYgbm8gdmFyaWFibGUgaXMgZGVmaW5lZCwgd2lsbCBiZSB0aGUgZmlyc3QgdGhhdCBhcHBlYXJzIGluIHRoZSBnZ3Bsb3QKICAgICAgICAgICAgICAgICAgICBCPWMoIlByb2xpZmVyYXRpdmUiLCJRdWllc2NlbnQiKSkKClBsb3RTY29yZXMoUmVzdWx0c0xpc3QgPSBkZl9sb2dtZWRpYW4sIENvbG9yVmFyaWFibGUgPSAiQ2VsbFR5cGUiLCBHcm91cGluZ1ZhcmlhYmxlPSJDb25kaXRpb24iLCAgbWV0aG9kID0ibG9nbWVkaWFuIiwgQ29sb3JWYWx1ZXMgPSBjZWxsVHlwZXNfY29sb3JzLCBDb25uZWN0R3JvdXBzPVRSVUUsIG5jb2wgPSAzLCBucm93ID0gMywgd2lkdGhUaXRsZT0yMCwgeV9saW1pdHMgPSBOVUxMLCBsZWdlbmRfbnJvdyA9IDIseGxhYj1OVUxMLCBjb25kX2NvaGVuZCA9IGNvbmRfY29oZW5kKQoKYGBgCgoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTB9CgpkZl9zc2dzZWEgPC0gQ2FsY3VsYXRlU2NvcmVzKGRhdGEgPSBjb3JyY291bnRzX21lcmdlLCBtZXRhZGF0YSA9IG1ldGFkYXRhX21lcmdlLCBtZXRob2QgPSAic3NHU0VBIiwgZ2VuZV9zZXRzID0gYmlkaXJlY3RzaWdzKQoKc2VuZXNjZW5jZV90cmlnZ2Vyc19jb2xvcnMgPC0gYygKICAibm9uZSIgPSAiI0U1NzM3MyIsICAjIFNvZnQgcmVkICAKICAiUmFkaWF0aW9uIiA9ICIjQkRCREJEIiwgICMgTWVkaXVtIGdyYXkgIAogICJETkEgZGFtYWdlIiA9ICIjNjRCNUY2IiwgICMgQnJpZ2h0ZXIgYmx1ZSAgCiAgIlRlbG9tZXJlIHNob3J0ZW5pbmciID0gIiM0RkMzRjciLCAgIyBWaXZpZCBza3kgYmx1ZSAgCiAgIkROQSBkZW1ldGh5bGF0aW9uIiA9ICIjQkE2OEM4IiwgICMgUmljaCBsYXZlbmRlciAgCiAgIk94aWRhdGl2ZSBzdHJlc3MiID0gIiNGREQ4MzUiLCAgIyBTdHJvbmcgeWVsbG93ICAKICAiQ29uZGl0aW9uZWQgTWVkaXVtIiA9ICIjRjI5OTRBIiwgICMgV2FybSBvcmFuZ2UgIAogICJPbmNvZ2VuZSIgPSAiIzgxQzc4NCIsICAjIE1lZGl1bSBncmVlbiAgCiAgIkxpcGlkIEFjY3VtdWxhdGlvbiIgPSAiI0U1NzM3MyIsICAjIENvcmFsICAKICAiQ2FsY2l1bSBpbmZsdXgiID0gIiMyNkE2OUEiLCAgIyBEZWVwIHRlYWwgIAogICJQbGFzbWEgbWVtYnJhbmUgZHlzcnVwdGlvbiIgPSAiI0QzMkYyRiIsICAjIFN0cm9uZyBzYWxtb24gIAogICJPU0tNIGZhY3RvcnMiID0gIiNGRkI3NEQiLCAgIyBCcmlnaHQgcGVhY2ggIAogICJZQVAgS08iID0gIiM5NTc1Q0QiICAjIERlZXAgcGFzdGVsIHB1cnBsZSAgCikKCmNlbGxUeXBlc19jb2xvcnMgPC0gYygKICAiRmlicm9ibGFzdCIgPSAiI0ZGNjk2MSIsICAgIyBTdHJvbmcgUGFzdGVsIFJlZCAgCiAgIktlcmF0aW5vY3l0ZSIgPSAiI0ZGQjM0NyIsICMgU3Ryb25nIFBhc3RlbCBPcmFuZ2UgIAogICJNZWxhbm9jeXRlIiA9ICIjRkZENzAwIiwgICAjIFN0cm9uZyBQYXN0ZWwgWWVsbG93ICAKICAiRW5kb3RoZWxpYWwiID0gIiM3N0RENzciLCAgIyBTdHJvbmcgUGFzdGVsIEdyZWVuICAKICAiTmV1cm9uYWwiID0gIiM3NzlFQ0IiLCAgICAgIyBTdHJvbmcgUGFzdGVsIEJsdWUgIAogICJNZXNlbmNoeW1hbCIgPSAiI0MyN0JBMCIgICAjIFN0cm9uZyBQYXN0ZWwgUHVycGxlICAKKQoKY29uZF9jb2hlbmQgPC0gbGlzdChBPWMoIlNlbmVzY2VudCIpLCAjIGlmIG5vIHZhcmlhYmxlIGlzIGRlZmluZWQsIHdpbGwgYmUgdGhlIGZpcnN0IHRoYXQgYXBwZWFycyBpbiB0aGUgZ2dwbG90CiAgICAgICAgICAgICAgICAgICAgQj1jKCJQcm9saWZlcmF0aXZlIiwiUXVpZXNjZW50IikpCgpQbG90U2NvcmVzKFJlc3VsdHNMaXN0ID0gZGZfc3Nnc2VhLCBDb2xvclZhcmlhYmxlID0gIkNlbGxUeXBlIiwgR3JvdXBpbmdWYXJpYWJsZT0iQ29uZGl0aW9uIiwgIG1ldGhvZCA9InNzR1NFQSIsIENvbG9yVmFsdWVzID0gY2VsbFR5cGVzX2NvbG9ycywgQ29ubmVjdEdyb3Vwcz1UUlVFLCBuY29sID0gMywgbnJvdyA9IDMsIHdpZHRoVGl0bGU9MjAsIHlfbGltaXRzID0gTlVMTCwgbGVnZW5kX25yb3cgPSAyLHhsYWI9TlVMTCwgY29uZF9jb2hlbmQgPSBjb25kX2NvaGVuZCkKCmBgYAoKCgoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTB9CgpkZl9yYW5raW5nIDwtIENhbGN1bGF0ZVNjb3JlcyhkYXRhID0gY29ycmNvdW50c19tZXJnZSwgbWV0YWRhdGEgPSBtZXRhZGF0YV9tZXJnZSwgbWV0aG9kID0gInJhbmtpbmciLCBnZW5lX3NldHMgPSBiaWRpcmVjdHNpZ3MpCgpzZW5lc2NlbmNlX3RyaWdnZXJzX2NvbG9ycyA8LSBjKAogICJub25lIiA9ICIjRTU3MzczIiwgICMgU29mdCByZWQgIAogICJSYWRpYXRpb24iID0gIiNCREJEQkQiLCAgIyBNZWRpdW0gZ3JheSAgCiAgIkROQSBkYW1hZ2UiID0gIiM2NEI1RjYiLCAgIyBCcmlnaHRlciBibHVlICAKICAiVGVsb21lcmUgc2hvcnRlbmluZyIgPSAiIzRGQzNGNyIsICAjIFZpdmlkIHNreSBibHVlICAKICAiRE5BIGRlbWV0aHlsYXRpb24iID0gIiNCQTY4QzgiLCAgIyBSaWNoIGxhdmVuZGVyICAKICAiT3hpZGF0aXZlIHN0cmVzcyIgPSAiI0ZERDgzNSIsICAjIFN0cm9uZyB5ZWxsb3cgIAogICJDb25kaXRpb25lZCBNZWRpdW0iID0gIiNGMjk5NEEiLCAgIyBXYXJtIG9yYW5nZSAgCiAgIk9uY29nZW5lIiA9ICIjODFDNzg0IiwgICMgTWVkaXVtIGdyZWVuICAKICAiTGlwaWQgQWNjdW11bGF0aW9uIiA9ICIjRTU3MzczIiwgICMgQ29yYWwgIAogICJDYWxjaXVtIGluZmx1eCIgPSAiIzI2QTY5QSIsICAjIERlZXAgdGVhbCAgCiAgIlBsYXNtYSBtZW1icmFuZSBkeXNydXB0aW9uIiA9ICIjRDMyRjJGIiwgICMgU3Ryb25nIHNhbG1vbiAgCiAgIk9TS00gZmFjdG9ycyIgPSAiI0ZGQjc0RCIsICAjIEJyaWdodCBwZWFjaCAgCiAgIllBUCBLTyIgPSAiIzk1NzVDRCIgICMgRGVlcCBwYXN0ZWwgcHVycGxlICAKKQoKY2VsbFR5cGVzX2NvbG9ycyA8LSBjKAogICJGaWJyb2JsYXN0IiA9ICIjRkY2OTYxIiwgICAjIFN0cm9uZyBQYXN0ZWwgUmVkICAKICAiS2VyYXRpbm9jeXRlIiA9ICIjRkZCMzQ3IiwgIyBTdHJvbmcgUGFzdGVsIE9yYW5nZSAgCiAgIk1lbGFub2N5dGUiID0gIiNGRkQ3MDAiLCAgICMgU3Ryb25nIFBhc3RlbCBZZWxsb3cgIAogICJFbmRvdGhlbGlhbCIgPSAiIzc3REQ3NyIsICAjIFN0cm9uZyBQYXN0ZWwgR3JlZW4gIAogICJOZXVyb25hbCIgPSAiIzc3OUVDQiIsICAgICAjIFN0cm9uZyBQYXN0ZWwgQmx1ZSAgCiAgIk1lc2VuY2h5bWFsIiA9ICIjQzI3QkEwIiAgICMgU3Ryb25nIFBhc3RlbCBQdXJwbGUgIAopCgpjb25kX2NvaGVuZCA8LSBsaXN0KEE9YygiU2VuZXNjZW50IiksICMgaWYgbm8gdmFyaWFibGUgaXMgZGVmaW5lZCwgd2lsbCBiZSB0aGUgZmlyc3QgdGhhdCBhcHBlYXJzIGluIHRoZSBnZ3Bsb3QKICAgICAgICAgICAgICAgICAgICBCPWMoIlByb2xpZmVyYXRpdmUiLCJRdWllc2NlbnQiKSkKClBsb3RTY29yZXMoUmVzdWx0c0xpc3QgPSBkZl9yYW5raW5nLCBDb2xvclZhcmlhYmxlID0gIkNlbGxUeXBlIiwgR3JvdXBpbmdWYXJpYWJsZT0iQ29uZGl0aW9uIiwgIG1ldGhvZCA9InJhbmtpbmciLCBDb2xvclZhbHVlcyA9IGNlbGxUeXBlc19jb2xvcnMsIENvbm5lY3RHcm91cHM9VFJVRSwgbmNvbCA9IDMsIG5yb3cgPSAzLCB3aWR0aFRpdGxlPTIwLCB5X2xpbWl0cyA9IE5VTEwsIGxlZ2VuZF9ucm93ID0gMix4bGFiPU5VTEwsIGNvbmRfY29oZW5kID0gY29uZF9jb2hlbmQpCgpgYGAKCgoKIyMgSGVhdG1hcCBmb3IgQ29oZW4ncyBECiAKCgoKYGBge3IgZmlnLndpZHRoPTE1LCBmaWcuaGVpZ2h0PTEyfQogClBsb3RTY29yZXMoZGF0YSA9IGNvcnJjb3VudHNfbWVyZ2UsIAogICAgICAgICAgIG1ldGFkYXRhID0gbWV0YWRhdGFfbWVyZ2UsICAKICAgICAgICAgICBnZW5lX3NldHM9YmlkaXJlY3RzaWdzLCAKICAgICAgICAgICBHcm91cGluZ1ZhcmlhYmxlPSJDb25kaXRpb24iLCAgCiAgICAgICAgICAgbWV0aG9kID0iYWxsIiwgICAKICAgICAgICAgICBuY29sID0gTlVMTCwgCiAgICAgICAgICAgbnJvdyA9IE5VTEwsIAogICAgICAgICAgIHdpZHRoVGl0bGU9MzAsIAogICAgICAgICAgIGxpbWl0cyA9IE5VTEwsICAgCiAgICAgICAgICAgdGl0bGU9Ik1hcnRoYW5kYW4gZXQgYWwuIDIwMTYiLCAKICAgICAgICAgICB0aXRsZXNpemUgPSAxMiwKICAgICAgICAgICBDb2xvclZhbHVlcyA9IE5VTEwpICAKCgojIG1pc3Npbmc6IAojIC0gY29tYmluZSBsZWdlbmRzCiMgLSB3cmFwIHRpdGxlCiMgLSB0aWx0IHggbGFiZWxzIHRvIDYwIGRlZ3JlZXMKIyAtIGNoYW5nZSBkZWZhdWx0IGNvbG9ycwojIHdyYXAgeCBsYWJlbHMgd2l0aCB3cmFwX3RpdGxlCiMgZ3JpZCB3aXRoIGNvbW1vbiBsZWdlbmRzIGh0dHBzOi8vc3VwcG9ydC5iaW9jb25kdWN0b3Iub3JnL3AvODczMTgvCgoKYGBgCiAKIAoKIyBJbmRpdmlkdWFsIEdlbmVzCgojIyMgVmlvbGluIEV4cHJlc3Npb24gUGxvdHMKCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9CgoKc2VuZXNjZW5jZV90cmlnZ2Vyc19jb2xvcnMgPC0gYygKICAibm9uZSIgPSAiI0U1NzM3MyIsICAjIFNvZnQgcmVkICAKICAiUmFkaWF0aW9uIiA9ICIjQkRCREJEIiwgICMgTWVkaXVtIGdyYXkgIAogICJETkEgZGFtYWdlIiA9ICIjNjRCNUY2IiwgICMgQnJpZ2h0ZXIgYmx1ZSAgCiAgIlRlbG9tZXJlIHNob3J0ZW5pbmciID0gIiM0RkMzRjciLCAgIyBWaXZpZCBza3kgYmx1ZSAgCiAgIkROQSBkZW1ldGh5bGF0aW9uIiA9ICIjQkE2OEM4IiwgICMgUmljaCBsYXZlbmRlciAgCiAgIk94aWRhdGl2ZSBzdHJlc3MiID0gIiNGREQ4MzUiLCAgIyBTdHJvbmcgeWVsbG93ICAKICAiQ29uZGl0aW9uZWQgTWVkaXVtIiA9ICIjRjI5OTRBIiwgICMgV2FybSBvcmFuZ2UgIAogICJPbmNvZ2VuZSIgPSAiIzgxQzc4NCIsICAjIE1lZGl1bSBncmVlbiAgCiAgIkxpcGlkIEFjY3VtdWxhdGlvbiIgPSAiI0U1NzM3MyIsICAjIENvcmFsICAKICAiQ2FsY2l1bSBpbmZsdXgiID0gIiMyNkE2OUEiLCAgIyBEZWVwIHRlYWwgIAogICJQbGFzbWEgbWVtYnJhbmUgZHlzcnVwdGlvbiIgPSAiI0QzMkYyRiIsICAjIFN0cm9uZyBzYWxtb24gIAogICJPU0tNIGZhY3RvcnMiID0gIiNGRkI3NEQiLCAgIyBCcmlnaHQgcGVhY2ggIAogICJZQVAgS08iID0gIiM5NTc1Q0QiICAjIERlZXAgcGFzdGVsIHB1cnBsZSAgCikKCgpJbmRpdmlkdWFsR2VuZXNfVmlvbGlucyhkYXRhID0gY29ycmNvdW50c19tZXJnZSwgbWV0YWRhdGEgPSBtZXRhZGF0YV9tZXJnZSwgZ2VuZXMgPSBjKCJDREtOMUEiLCAiQ0RLTjJBIiwgIkdMQjEiLCJUUDUzIiwiQ0NMMiIpLCBHcm91cGluZ1ZhcmlhYmxlID0gIkNvbmRpdGlvbiIsIHBsb3Q9VCwgbmNvbD1OVUxMLCBucm93PTIsIGRpdmlkZT0iQ2VsbFR5cGUiLCBpbnZlcnRfZGl2aWRlPUZBTFNFLENvbG9yVmFsdWVzPXNlbmVzY2VuY2VfdHJpZ2dlcnNfY29sb3JzLCBwb2ludFNpemU9MiwgQ29sb3JWYXJpYWJsZT0iU2VuZXNjZW50VHlwZSIsIHRpdGxlPSJTZW5lc2NlbmNlIiwgd2lkdGhUaXRsZT0xNix5X2xpbWl0cyA9IE5VTEwsbGVnZW5kX25yb3c9NCwgeGxhYj0iQ29uZGl0aW9uIixjb2xvcmxhYj0iIikgCmBgYAoKCgojIyMgQ29ycmVsYXRpb24gSGVhdG1hcAoKCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTR9Cm9wdGlvbnMoZXJyb3I9cmVjb3ZlcikKQ29ycmVsYXRpb25IZWF0bWFwKGRhdGE9Y29ycmNvdW50c19tZXJnZSwgCiAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSA9IG1ldGFkYXRhX21lcmdlLCAKICAgICAgICAgICAgICAgICAgIGdlbmVzPWMoIkNES04xQSIsICJDREtOMkEiLCAiR0xCMSIsIlRQNTMiLCJDQ0wyIiksIAogICAgICAgICAgICAgICAgICAgc2VwYXJhdGUuYnkgPSAiQ29uZGl0aW9uIiwgCiAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAicGVhcnNvbiIsICAKICAgICAgICAgICAgICAgICAgIGNvbG9ybGlzdCA9IGxpc3QobG93ID0gIiMzRjQxOTMiLCBtaWQgPSAiI0Y5RjRBRSIsIGhpZ2ggPSAiI0I0NDE0MSIpLAogICAgICAgICAgICAgICAgICAgbGltaXRzX2NvbG9yc2NhbGUgPSBjKC0xLDAsMSksIAogICAgICAgICAgICAgICAgICAgd2lkdGhUaXRsZSA9IDE2LCAKICAgICAgICAgICAgICAgICAgIHRpdGxlID0gInRlc3QiLCAKICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJfcm93cyA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgY2x1c3Rlcl9jb2x1bW5zID0gVFJVRSwgIAogICAgICAgICAgICAgICAgICAgZGV0YWlsZWRyZXN1bHRzID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgbGVnZW5kX3Bvc2l0aW9uPSJyaWdodCIsCiAgICAgICAgICAgICAgICAgICB0aXRsZXNpemU9MjApCgoKYGBgCgoKCgojIyMgRXhwcmVzc2lvbiBIZWF0bWFwcwoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9Cm9wdGlvbnMoZXJyb3I9cmVjb3ZlcikKCmFubm90YXRpb25fY29sb3JzIDwtIGxpc3QoCiAgQ2VsbFR5cGUgPSBjKAogICAgIkZpYnJvYmxhc3QiICAgPSAiI0ZGNjk2MSIsICAgIyBTdHJvbmcgUGFzdGVsIFJlZCAgCiAgICAiS2VyYXRpbm9jeXRlIiA9ICIjRkZCMzQ3IiwgICAjIFN0cm9uZyBQYXN0ZWwgT3JhbmdlICAKICAgICJNZWxhbm9jeXRlIiAgID0gIiNGRkQ3MDAiLCAgICMgU3Ryb25nIFBhc3RlbCBZZWxsb3cgIAogICAgIkVuZG90aGVsaWFsIiAgPSAiIzc3REQ3NyIsICAgIyBTdHJvbmcgUGFzdGVsIEdyZWVuICAKICAgICJOZXVyb25hbCIgICAgID0gIiM3NzlFQ0IiLCAgICMgU3Ryb25nIFBhc3RlbCBCbHVlICAKICAgICJNZXNlbmNoeW1hbCIgID0gIiNDMjdCQTAiICAgICMgU3Ryb25nIFBhc3RlbCBQdXJwbGUgIAogICksCiAgQ29uZGl0aW9uID0gYygKICAgICJTZW5lc2NlbnQiICAgICA9ICIjNjVBQzdDIiwgICMgRXhhbXBsZSBjb2xvcjogZ3JlZW5pc2gKICAgICJQcm9saWZlcmF0aXZlIiA9ICIjNUY5MEQ0IiwgICMgRXhhbXBsZSBjb2xvcjogYmx1ZWlzaAogICAgIlF1aWVzY2VudCIgICAgID0gIiNFREEwM0UiICAgIyBFeGFtcGxlIGNvbG9yOiBvcmFuZ2UKICApCikKCkV4cHJlc3Npb25IZWF0bWFwKGRhdGE9Y29ycmNvdW50c19tZXJnZSwgCiAgICAgICAgICAgICAgICAgIG1ldGFkYXRhID0gbWV0YWRhdGFfbWVyZ2UsIAogICAgICAgICAgICAgICAgICBnZW5lcz1jKCJDREtOMUEiLCAiQ0RLTjJBIiwgIkdMQjEiLCJUUDUzIiwiQ0NMMiIpLCAgCiAgICAgICAgICAgICAgICAgIGFubm90YXRlLmJ5ID0gYygiQ2VsbFR5cGUiLCJDb25kaXRpb24iKSwKICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBhbm5vdGF0aW9uX2NvbG9ycywKICAgICAgICAgICAgICAgICAgY29sb3JsaXN0ID0gbGlzdChsb3cgPSAiIzNGNDE5MyIsIG1pZCA9ICIjRjlGNEFFIiwgaGlnaCA9ICIjQjQ0MTQxIiksCiAgICAgICAgICAgICAgICAgIGNsdXN0ZXJfcm93cyA9IFRSVUUsIAogICAgICAgICAgICAgICAgICBjbHVzdGVyX2NvbHVtbnMgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgdGl0bGUgPSAidGVzdCIsIAogICAgICAgICAgICAgICAgICB0aXRsZXNpemUgPSAyMCwKICAgICAgICAgICAgICAgICAgbGVnZW5kX3Bvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICAgICAgICAgICAgc2NhbGVfcG9zaXRpb249InJpZ2h0IikKCmBgYAoKCgojIyMgUk9DL0FVQyAKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fQoKY2VsbFR5cGVzX2NvbG9ycyA8LSBjKAogICJGaWJyb2JsYXN0IiA9ICIjRkY2OTYxIiwgICAjIFN0cm9uZyBQYXN0ZWwgUmVkICAKICAiS2VyYXRpbm9jeXRlIiA9ICIjRkZCMzQ3IiwgIyBTdHJvbmcgUGFzdGVsIE9yYW5nZSAgCiAgIk1lbGFub2N5dGUiID0gIiNGRkQ3MDAiLCAgICMgU3Ryb25nIFBhc3RlbCBZZWxsb3cgIAogICJFbmRvdGhlbGlhbCIgPSAiIzc3REQ3NyIsICAjIFN0cm9uZyBQYXN0ZWwgR3JlZW4gIAogICJOZXVyb25hbCIgPSAiIzc3OUVDQiIsICAgICAjIFN0cm9uZyBQYXN0ZWwgQmx1ZSAgCiAgIk1lc2VuY2h5bWFsIiA9ICIjQzI3QkEwIiAgICMgU3Ryb25nIFBhc3RlbCBQdXJwbGUgIAopCgpST0NhbmRBVUNwbG90KGNvcnJjb3VudHNfbWVyZ2UsIAogICAgICAgICAgICAgIG1ldGFkYXRhX21lcmdlLCAKICAgICAgICAgICAgICBjb25kaXRpb25fdmFyID0gIkNvbmRpdGlvbiIsIAogICAgICAgICAgICAgIGNsYXNzID0gIlNlbmVzY2VudCIsIAogICAgICAgICAgICAgIGdlbmVzPWMoIkNES04xQSIsICJDREtOMkEiLCAiR0xCMSIsIlRQNTMiLCJDQ0wyIiksIAogICAgICAgICAgICAgIGdyb3VwX3Zhcj0iQ2VsbFR5cGUiLAogICAgICAgICAgICAgIHBsb3RfdHlwZSA9ICJhbGwiLAogICAgICAgICAgICAgIGhlYXRtYXBfcGFyYW1zID0gbGlzdChjb2wgPSBsaXN0KCAiI0Y5RjRBRSIgLCIjQjQ0MTQxIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9IGMoMC41LDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbHVzdGVyX3Jvd3M9VCksCiAgICAgICAgICAgICAgcm9jX3BhcmFtcyA9IGxpc3QobnJvdz0yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5jb2w9MiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcnM9Y2VsbFR5cGVzX2NvbG9ycyksCiAgICAgICAgICAgICAgY29tbW9tcGxvdF9wYXJhbXMgPSBsaXN0KHdpZHRocz1jKDAuNSwwLjUpKSkKCgpgYGAKCiMjIyBDb2hlbidzIGQKCmBgYHtyfQpDb2hlbkRIZWF0bWFwKGNvcnJjb3VudHNfbWVyZ2UsIAogICAgICAgICAgICAgIG1ldGFkYXRhX21lcmdlLCAKICAgICAgICAgICAgICBnZW5lcz1jKCJDREtOMUEiLCAiQ0RLTjJBIiwgIkdMQjEiLCJUUDUzIiwiQ0NMMiIpLAogICAgICAgICAgICAgIGNvbmRpdGlvbl92YXIgPSAiQ29uZGl0aW9uIiwgCiAgICAgICAgICAgICAgY2xhc3MgPSAiU2VuZXNjZW50IiwgCiAgICAgICAgICAgICAgZ3JvdXBfdmFyID0gIkNlbGxUeXBlIiwKICAgICAgICAgICAgICB0aXRsZSA9IE5VTEwsCiAgICAgICAgICAgICAgd2lkdGhUaXRsZSA9IDE2LAogICAgICAgICAgICAgIGhlYXRtYXBfcGFyYW1zID0gbGlzdChjb2wgPSBsaXN0KCAiI0Y5RjRBRSIgLCIjQjQ0MTQxIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJfcm93cz1UKSkKYGBgCgojIyMgUENBIHdpdGggZ2VuZXMgZnJvbSBzaWduYXR1cmUgb25seQoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NH0KCkNlbGxUeXBlY29scyA9IGMoCiAgIkZpYnJvYmxhc3QiICAgPSAiI0ZGNjk2MSIsICAgIyBTdHJvbmcgUGFzdGVsIFJlZCAgCiAgIktlcmF0aW5vY3l0ZSIgPSAiI0ZGQjM0NyIsICAgIyBTdHJvbmcgUGFzdGVsIE9yYW5nZSAgCiAgIk1lbGFub2N5dGUiICAgPSAiI0ZGRDcwMCIsICAgIyBTdHJvbmcgUGFzdGVsIFllbGxvdyAgCiAgIkVuZG90aGVsaWFsIiAgPSAiIzc3REQ3NyIsICAgIyBTdHJvbmcgUGFzdGVsIEdyZWVuICAKICAiTmV1cm9uYWwiICAgICA9ICIjNzc5RUNCIiwgICAjIFN0cm9uZyBQYXN0ZWwgQmx1ZSAgCiAgIk1lc2VuY2h5bWFsIiAgPSAiI0MyN0JBMCIgICAgIyBTdHJvbmcgUGFzdGVsIFB1cnBsZSAgCikKCnNlbmNvbHMgPC0gYygKICAiU2VuZXNjZW50IiA9ICIjRDMyRjJGIiwgICMgU3Ryb25nIHNhbG1vbiAgCiAgIlF1aWVzY2VudCIgPSAiI0ZGQjc0RCIsICAjIEJyaWdodCBwZWFjaCAgCiAgIlByb2xpZmVyYXRpdmUiID0gIiM5NTc1Q0QiICAjIERlZXAgcGFzdGVsIHB1cnBsZSAgCikKCnBsb3RQQ0EoZGF0YT1jb3JyY291bnRzX21lcmdlLCAKICAgICAgICBtZXRhZGF0YT1tZXRhZGF0YV9tZXJnZSwgCiAgICAgICAgZ2VuZXM9YygiQ0RLTjFBIiwgIkNES04yQSIsICJHTEIxIiwiVFA1MyIsIkNDTDIiKSwgCiAgICAgICAgc2NhbGU9RkFMU0UsIAogICAgICAgIGNlbnRlcj1UUlVFLCAKICAgICAgICBQQ3M9bGlzdChjKDEsMiksIGMoMiwzKSwgYygzLDQpKSwgCiAgICAgICAgQ29sb3JWYXJpYWJsZT0iQ29uZGl0aW9uIiwKICAgICAgICBDb2xvclZhbHVlcz1zZW5jb2xzLAogICAgICAgIHBvaW50U2l6ZT01LAogICAgICAgIGxlZ2VuZF9ucm93PTEsIAogICAgICAgIG5jb2w9MywgCiAgICAgICAgbnJvdz1OVUxMKQpgYGAKCgo=